﻿using AJWPFAdmin.Core.Components.AJTable.ViewModels;
using AJWPFAdmin.Core.Crypto.AES;
using AJWPFAdmin.Core.Crypto.RSA;
using AJWPFAdmin.Core.Crypto.SMCrypto;
using AJWPFAdmin.Core.Enums;
using AJWPFAdmin.Core.ExtensionMethods;
using AJWPFAdmin.Core.Logger;
using AJWPFAdmin.Core.Models;
using AJWPFAdmin.Core.Models.EF.Tables;
using AJWPFAdmin.Core.Utils;
using AJWPFAdmin.Services.EF;
using AJWPFAdmin.Services.EF.TableExts;
using Azure;
using com.github.xiangyuecn.rsacsharp;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using Masuit.Tools.Reflection;
using Masuit.Tools.Security;
using MaterialDesignThemes.Wpf;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using Prism.Ioc;
using Quartz.Logging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Windows;
using System.Windows.Interop;

namespace AJWPFAdmin.Services.AppointAPI
{
    public class LangfangAppointAPI : AppointAPIBase
    {
        private APIConfig _apiConfig;

        private static readonly Dictionary<CarPlateColor, string> _customCarPlateColorMapps = new Dictionary<CarPlateColor, string>
        {
            {CarPlateColor.蓝牌, "0"},
            {CarPlateColor.黄牌, "1"},
            {CarPlateColor.白牌, "2"},
            {CarPlateColor.黑牌, "3"},
            {CarPlateColor.新能源绿牌, "4"},
            {CarPlateColor.渐变绿牌, "5"},
            {CarPlateColor.新能源黄牌, "6"},
            {CarPlateColor.其他, "7"},
        };

        public LangfangAppointAPI(ApplicationType appType,
            SystemConfigDictionary cfg,
            IContainerProvider svcProvider) : base(appType, cfg, svcProvider)
        {

        }

        protected override void OnAPILogsRaised(PassagewayDirection? direction,
            string logs)
        {
            base.OnAPILogsRaised(direction, logs);
        }

        public override Task<ProcessResult> UploadCarInfoAsync(CarInfoParams @params)
        {
            /*
             * {
                "CLLX":"",//车辆类型（0：场外运输1：场内运输2：非道路移动机械）
                 "CPH":"",//车牌号
                "CPLX":"",//车牌类型（0：蓝牌1：黄牌2：白牌3：黑牌4：绿牌5：渐变绿牌6：黄绿双拼7：未知）
                "CLSBDH":"",//车辆识别代号
                "CPHYS":"",//车牌号颜色
                "PFJD":"",//排放阶段
                "RLZL":"",//燃料种类
                "SSDWTYSHDM":"",//所属单位统一社会代码
                }
             */

            var carType = (CarTypeEnum)((int)@params.CarInfo.TypeId);

            return PostAsync("updatejkCljbxx.do", null,
                new Dictionary<string, string>
                {
                    {"CLLX", (carType == CarTypeEnum.进出厂车 || carType == CarTypeEnum.固定车) 
                            ? "0" : carType == CarTypeEnum.厂内运输车 ? "1" : "2"  },
                    {"CPH", @params.CarInfo.CarNo },
                    {"CPLX", _customCarPlateColorMapps[@params.CarInfo.PlateColor] },
                    {"CLSBDH", carType != CarTypeEnum.非道路移动机械  
                                ? @params.CarInfo.VIN : @params.CarInfo.PIN},
                    {"CPHYS", @params.CarInfo.PlateColor.ToString()},
                    {"PFJD", @params.CarInfo.EmissionStandard.ToString()},
                    {"RLZL", @params.CarInfo.FuelTypeName},
                    {"SSDWTYSHDM",_apiConfig.CompanyCode }
                },
                needUILog: true,
                direction: @params.Passageway?.Direction);
        }

        public override async Task<ProcessResult> UploadShippingRecordAsync(ShippingRecordParams @params)
        {
            ProcessResult result;
            var response = new UploadShippingRecordResponse();

            /*
             * {
                "JLBH":"",//记录编号
                "JKDSBBH":"",//监控点设备编号 
                "TGSH":"",//通过时间
                "CPH":"",//车牌号
                "CLZZL":"",//车辆总质量 
                "CPZT":"",//车牌抓图
                "CSZT":"",//车身抓图
                }
             */

            var (carHead, carPlate, _) = @params.Record.GetWatchPositionImageFile(@params.Record.Direction);

            var carNo = @params.Record.CarNo;

            result = await  PostAsync("updateJkgcJcxx.do", null,
                new Dictionary<string, string>
                {
                    {"JLBH", @params.Record.Id.ToString() },

                    {"JKDSBBH", @params.Record.Direction == PassagewayDirection.进 ?                             @params.Record.DeviceCode : @params.Record.OutDeviceCode },

                    {"TGSH", @params.Record.Direction == PassagewayDirection.进 ?
                            @params.Record.ShipStartDate.GetValueOrDefault()
                            .ToString("yyyy-MM-dd HH:mm:ss")
                            : @params.Record.ShipEndDate.GetValueOrDefault()
                            .ToString("yyyy-MM-dd HH:mm:ss")},

                    {"CPH", carNo },

                    {"CLZZL", @params.Record.Direction == PassagewayDirection.进 ?                               @params.Record.InGoodsVolume.ToString() 
                            : @params.Record.OutGoodsVolume.ToString() },

                    {"CPZT", _carIdentificationConfig.CompleteFileUrl(carNo,  carHead) },

                    {"CSZT", _carIdentificationConfig.CompleteFileUrl(carNo, carPlate) }
                },
                needUILog: true,
                direction: @params.Record.Direction);

            if (!result.Success)
            {
                result.Attach = response;
                return result;
            }

            // 过车记录上传成功,记录号加1
            response.RecordNum++;
            result.Attach = response;

            return result;

        }



        private async Task<ProcessResult> PostAsync(
            string method,
            JObject body,
            Dictionary<string, string> query,
            bool isListResponse = false, bool needUILog = false,
            PassagewayDirection? direction = null)
        {
            var result = new ProcessResult();

            StringBuilder stringBuilder = null;

            using var httpClient = CreateClient();

            try
            {
                var bodyStr = body == null ? "{}" : body.ToString(Newtonsoft.Json.Formatting.None);
                var queryStr = string.Empty;
                if (query?.Count > 0)
                {
                    queryStr = $"?{string.Join("&", query.Select(p => $"{p.Key}={HttpUtility.UrlEncode(p.Value)}"))}";
                }

                stringBuilder = new StringBuilder();

                stringBuilder.Append($"{KeyDescription} {method}:\r\n");

                stringBuilder.Append($"请求body参数:{bodyStr}\r\n");
                stringBuilder.Append($"请求查询参数:{queryStr}\r\n");

                var content = new StringContent(bodyStr, Encoding.UTF8, "applicatin/json");

                var res = await httpClient.PostAsync($"http://{_apiConfig.IPAndPort}/ShengTingGongDi/syncShengTing2/{method}{queryStr}", content);

                var responseStr = await res.Content.ReadAsStringAsync();

                stringBuilder.Append($"接口响应源内容\r\n:{responseStr}");

                if (res.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var response = CommonUtil.TryGetJSONObject<APIResponse>(responseStr) ?? new APIResponse
                    {
                        STATUS = -1,
                        MESSAGE = "解析接口返回失败",
                    };

                    if (response.STATUS == 200)
                    {
                        result.SetSuccess();
                    }
                    else
                    {
                        result.SetError(response.MESSAGE);
                    }

                }
                else
                {
                    result.SetError($"接口访问失败:{res.StatusCode}");
                }

                var logContent = stringBuilder.ToString();
                _logger.Error(logContent);
                if (needUILog)
                {
                    OnAPILogsRaised(direction, logContent);
                }

            }
            catch (Exception e)
            {
                var logContent = e.Message;
                stringBuilder.Append($"{logContent}\r\n");
                result.SetError(logContent, e);
                if (stringBuilder != null)
                {
                    stringBuilder.Append(e.StackTrace);
                    _logger.Error(stringBuilder.ToString());
                }
                if (needUILog)
                {
                    OnAPILogsRaised(direction, stringBuilder.ToString());
                }
            }
            return result;
        }

        private HttpClient CreateClient()
        {
            var httpClient = new HttpClient();

            return httpClient;
        }

        public override Task ConvertToCustomConfig(bool isReal)
        {
            _apiConfig = CommonUtil.TryGetJSONObject<APIConfig>(Config.StringValue) ?? new APIConfig();
            _customAPIConfig = _apiConfig;
            AutoUploadDataVerification = _apiConfig.AutoUploadDataVerification;

            if (isReal)
            {

            }
            else
            {
                _ = GetSchemas();
            }

            return Task.CompletedTask;
        }

        public new void Dispose()
        {

        }

        public class APIConfig : APIConfigBase
        {
            [DynamicFormItemDefine("接口IP和端口号")]
            public string IPAndPort { get; set; }

            //[DynamicFormItemDefine("设备编号")]
            //public string DeviceNo { get; set; }

            [DynamicFormItemDefine("企业法人代码")]
            public string CompanyCode { get; set; }

        }

        public class APIResponse
        {
            public int STATUS { get; set; }
            public string MESSAGE { get; set; }
        }
    }
}
